package com.spark.market.service.manager.mq.consumer;

import com.alibaba.fastjson.JSONObject;
import com.rabbitmq.client.Channel;
import com.spark.market.api.mq.ItemStockMqMessage;
import com.spark.market.common.constants.LogFileName;
import com.spark.market.common.utils.AssertUtils;
import com.spark.market.common.utils.LoggerUtils;
import com.spark.market.dal.entity.OrderLogDo;
import com.spark.market.service.OrderCmdCoreService;
import com.spark.market.service.manager.ItemManager;
import org.slf4j.Logger;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.IOException;

/**
 * @author zwd
 * @date 2021/6/27
 * @email zwd@hhh.com
 */
@Component
public class ItemStockConsumerManager {
    Logger LOGGER = LoggerUtils.Logger(LogFileName.MARKET_LOG);
    @Resource
    private ItemManager itemManager;

    @Resource
    private OrderCmdCoreService orderCmdCoreService;

    @RabbitListener(queues = {"${mq.producer.item.stock.queue-name}"},ackMode = "MANUAL")
    public void receiveItemStockMsg(ItemStockMqMessage itemStockMqMessage, Channel channel, Message message) throws IOException {
        try {
            AssertUtils.isNotNull(itemStockMqMessage, "itemStockMqMessage is null");
            boolean res = itemManager.decreaseStock(itemStockMqMessage.getItemId(), itemStockMqMessage.getAmount());
            // 确认消息已经消费成功
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (Exception e) {
            LOGGER.error("MQ消息处理异常，队列属性:{}，消息：{}", message.getMessageProperties().toString(), JSONObject.toJSONString(itemStockMqMessage), e);
            try {
                // TODO 保存消息到数据库
                OrderLogDo orderLogDo = new OrderLogDo();
                orderLogDo.setOrderId(itemStockMqMessage.getOrderId());
                orderLogDo.setCount(itemStockMqMessage.getAmount());
                orderLogDo.setUserId(itemStockMqMessage.getUserID());
                orderLogDo.setItemId(itemStockMqMessage.getItemId());
                orderLogDo.setExtra("消费消息失败");
                orderCmdCoreService.savaOrderLog(orderLogDo);
                // 确认消息已经消费成功
                channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
            }catch (Exception dbe){
                LOGGER.error("保存异常MQ消息到数据库异常，放到死性队列，消息体：{}", JSONObject.toJSONString(itemStockMqMessage), dbe);
                // 确认消息将消息放到死信队列
                channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, false);
            }
        }
    }
}
